package com.open.capacity.finance.task.gdszcz;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.open.capacity.finance.config.Globals;
import com.open.capacity.finance.entity.SpringScheduledCron;
import com.open.capacity.finance.service.SpringScheduledCronService;
import com.open.capacity.finance.task.ScheduledOfTask;
import com.open.capacity.finance.util.GDSZCZUtils;
import com.open.capacity.reptile.constant.GDSZCZConstant;
import com.open.capacity.reptile.dto.gdszcz.request.CommonRequest;
import com.open.capacity.reptile.dto.gdszcz.response.CommonResponse;
import com.open.capacity.reptile.dto.gdszcz.response.pay.babgtinfo.BaBgtInfoData;
import com.open.capacity.reptile.dto.gdszcz.response.pay.paycard.PayCardData;
import com.open.capacity.reptile.dto.gdszcz.response.pay.payplan.PayPlanData;
import com.open.capacity.reptile.dto.gdszcz.response.pay.payvoucher.PayVoucherData;
import com.open.capacity.reptile.entity.GdszczBaBgtInfo;
import com.open.capacity.reptile.entity.GdszczPayCardRecord;
import com.open.capacity.reptile.entity.GdszczPayPlanVoucher;
import com.open.capacity.reptile.entity.GdszczPayVoucherBill;
import com.open.capacity.reptile.service.GdszczBaBgtInfoService;
import com.open.capacity.reptile.service.GdszczPayCardRecordService;
import com.open.capacity.reptile.service.GdszczPayPlanVoucherService;
import com.open.capacity.reptile.service.GdszczPayVoucherBillService;
import com.open.capacity.reptile.util.HttpUtils;
import com.open.capacity.user.model.SysCompany;
import com.open.capacity.user.service.SysConfigService;
import com.open.capacity.utils.DateUtil;
import com.open.capacity.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

/**
 * 支付数据同步
 */
@Component
@Slf4j
public class PayDataTask implements ScheduledOfTask {

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private GdszczPayCardRecordService payCardRecordService;

    @Autowired
    private GdszczPayVoucherBillService payVoucherBillService;

    @Autowired
    private GdszczPayPlanVoucherService payPlanVoucherService;

    @Autowired
    private GdszczBaBgtInfoService baBgtInfoService;

    @Autowired
    private SpringScheduledCronService cronService;

    @Autowired
    private SysConfigService configService;

    @Autowired
    private GDSZCZUtils gdszczUtils;

    Integer cronId = null;

    @Override
    public void setCronId(Integer cronId) {
        this.cronId = cronId;
    }

    @Override
    public void execute() {
        try {
            log.info("start excute PayDataTask");

            String updateStartTime = "";
            SpringScheduledCron cron = cronService.findById(cronId);
            if (cron != null && cron.getLastExcuteTime() != null) {
                updateStartTime = DateUtil.format(cron.getLastExcuteTime());
            }

            //异步将离线文件写入数据库
            String finalUpdateStartTime = updateStartTime;
            CompletableFuture.runAsync(() -> {
                trigger(finalUpdateStartTime);
            }, taskExecutor);

        } catch (Throwable e) {
            log.error("execute process has error(Throwable) : ", e);
        }
    }

    @Override
    public void trigger(String startTime) {
        String updateStartTime = String.valueOf(DateUtil.parseDate(startTime).getTime() / 1000);
        // 记录开始时间
        long start = System.currentTimeMillis();
        Date now = new Date();
        int currentYear = DateUtil.getYear();
        int fiscalYear = Integer.parseInt(configService.findByKey("gdszcz_fiscalYear").getCnfValue());
        if (StringUtil.isNotEmpty(startTime)) {
            fiscalYear = DateUtil.getYear(DateUtil.parseDate(startTime.substring(0, 10)));
        }

        try {
            Header[] headers = gdszczUtils.packetHeaders();

            String agencyCodeStr = configService.findByKey("gdszcz_agencyCode").getCnfValue();
            String[] agencyCodeArray = agencyCodeStr.split(",");
            for (String agencyCode : agencyCodeArray) {
                Optional<SysCompany> first = Globals.companyList.stream().filter(company -> company.getAgencyCode().equals(agencyCode)).findFirst();
                int startYear = fiscalYear;
                while (startYear <= currentYear) {
                    if (startYear <= 2021) {//不同步2021年前的数据
                        startYear++;
                        continue;
                    }
                    //1. 支付凭证
                    syncPayVoucherBill(agencyCode, startYear, updateStartTime, first, headers);

                    //2. 用款计划
                    syncPayPlanVoucher(agencyCode, startYear, updateStartTime, first, headers);

                    //4. 公务卡消费记录
                    syncPayPaycardDetail(agencyCode, startYear, updateStartTime, first, headers);

                    //5. 指标信息查询
                    syncBabgtInfo(agencyCode, startYear, updateStartTime, first, headers);

                    startYear++;
                }
            }

            //更新最后执行成功时间
            cronService.updateExcuteTime(cronId, now, 1, null, (System.currentTimeMillis() - start) / 60000);
        } catch (Exception e) {
            log.error(e.getMessage());
            //更新最后执行失败时间
            cronService.updateExcuteTime(cronId, now, 0, e.getMessage(), (System.currentTimeMillis() - start) / 60000);
        }
    }

    /**
     * pay_voucher_bill 集中支付凭证
     */
    private void syncPayVoucherBill(String agencyCode, Integer fiscalYear, String updateStartTime, Optional<SysCompany> first, Header[] headers) throws IOException {
        CommonRequest request = gdszczUtils.packetRequest(agencyCode, fiscalYear, updateStartTime, "pay_voucher_bill");

        String responseVoucherPay = HttpUtils.requestForJson(MessageFormat.format(GDSZCZConstant.pay_voucher_query_url, configService.findByKey("gdszcz_apiurl").getCnfValue()), JSONObject.toJSONString(request), headers);

        CommonResponse<List<GdszczPayVoucherBill>> responseVoucherPayData = JSONObject.parseObject(responseVoucherPay, new TypeReference<CommonResponse<List<GdszczPayVoucherBill>>>() {
        });
        log.info(String.format("pay_voucher_query_url--请求:agencyCode:{},fiscalYear:{},updateStartTime:{};响应:resultCode：{},resultMessage:{},resultCount:{}"), request.getAgencyCode(), request.getFiscalYear(), request.getUpdateStartTime(), responseVoucherPayData.getResultCode(), responseVoucherPayData.getResultMessage(), responseVoucherPayData.getData().size());
        if (responseVoucherPayData.getResultCode().equals("000")) {
            for (GdszczPayVoucherBill s : responseVoucherPayData.getData()) {
                if (s.getIsDelete() == 1) { //忽略已经删除的数据
                    continue;
                }
                int existCount = payVoucherBillService.exists(s.getId());
                if (existCount == 0) {
                    if (first.isPresent()) {
                        s.setAgencyCode(first.get().getId());
                    }
                    payVoucherBillService.save(s);
                }
            }
        }
    }

    /**
     * pay_plan_voucher 用款计划
     */
    private void syncPayPlanVoucher(String agencyCode, Integer fiscalYear, String updateStartTime, Optional<SysCompany> first, Header[] headers) throws IOException {
        CommonRequest request = gdszczUtils.packetRequest(agencyCode, fiscalYear, updateStartTime, "pay_plan_voucher");
        String responsePlanPay = HttpUtils.requestForJson(MessageFormat.format(GDSZCZConstant.pay_plan_query_url, configService.findByKey("gdszcz_apiurl").getCnfValue()), JSONObject.toJSONString(request), headers);

        CommonResponse<List<GdszczPayPlanVoucher>> responsePlanPayData = JSONObject.parseObject(responsePlanPay, new TypeReference<CommonResponse<List<GdszczPayPlanVoucher>>>() {
        });
        log.info(String.format("pay_plan_query_url--请求:agencyCode:{},fiscalYear:{},updateStartTime:{};响应:resultCode：{},resultMessage:{},resultCount:{}"), request.getAgencyCode(), request.getFiscalYear(), request.getUpdateStartTime(), responsePlanPayData.getResultCode(), responsePlanPayData.getResultMessage(), responsePlanPayData.getData().size());
        if (responsePlanPayData.getResultCode().equals("000")) {
            for (GdszczPayPlanVoucher s : responsePlanPayData.getData()) {
                int existCount = payPlanVoucherService.exists(s.getPlanId());
                if (existCount == 0) {
                    if (first.isPresent()) {
                        s.setAgencyCode(first.get().getId());
                    }
                    payPlanVoucherService.save(s);
                }
            }
        }
    }

    /**
     * pay_paycard_detail  公务卡消费
     */
    private void syncPayPaycardDetail(String agencyCode, Integer fiscalYear, String updateStartTime, Optional<SysCompany> first, Header[] headers) throws IOException {
        CommonRequest request = gdszczUtils.packetRequest(agencyCode, fiscalYear, updateStartTime, "pay_paycard_detail");
        String responsePayCard = HttpUtils.requestForJson(MessageFormat.format(GDSZCZConstant.pay_card_query_url, configService.findByKey("gdszcz_apiurl").getCnfValue()), JSONObject.toJSONString(request), headers);

        CommonResponse<List<GdszczPayCardRecord>> responsePayCardData = JSONObject.parseObject(responsePayCard, new TypeReference<CommonResponse<List<GdszczPayCardRecord>>>() {
        });
        log.info(String.format("pay_card_query_url--请求:agencyCode:{},fiscalYear:{},updateStartTime:{};响应:resultCode：{},resultMessage:{},resultCount:{}"), request.getAgencyCode(), request.getFiscalYear(), request.getUpdateStartTime(), responsePayCardData.getResultCode(), responsePayCardData.getResultMessage(), responsePayCardData.getData().size());
        if (responsePayCardData.getResultCode().equals("000")) {
            for (GdszczPayCardRecord s : responsePayCardData.getData()) {
                int existCount = payCardRecordService.exists(s.getId());
                if (existCount == 0) {
                    if (first.isPresent()) {
                        s.setAgencyCode(first.get().getId());
                    }
                    payCardRecordService.save(s);
                }
            }
        }
    }


    /**
     * zxy_cx_ba_bgt_info  指标信息查询
     */
    private void syncBabgtInfo(String agencyCode, Integer fiscalYear, String updateStartTime, Optional<SysCompany> first, Header[] headers) throws IOException {
        CommonRequest request = gdszczUtils.packetRequest(agencyCode, fiscalYear, updateStartTime, "zxy_cx_ba_bgt_info");
        String responseBaBgtInfo = HttpUtils.requestForJson(MessageFormat.format(GDSZCZConstant.zxy_cx_ba_bgt_info_query_url, configService.findByKey("gdszcz_apiurl").getCnfValue()), JSONObject.toJSONString(request), headers);

        CommonResponse<List<GdszczBaBgtInfo>> responseBaBgtInfoData = JSONObject.parseObject(responseBaBgtInfo, new TypeReference<CommonResponse<List<GdszczBaBgtInfo>>>() {
        });
        log.info(String.format("zxy_cx_ba_bgt_info_query_url--请求:agencyCode:{},fiscalYear:{},updateStartTime:{};响应:resultCode：{},resultMessage:{},resultCount:{}"), request.getAgencyCode(), request.getFiscalYear(), request.getUpdateStartTime(), responseBaBgtInfoData.getResultCode(), responseBaBgtInfoData.getResultMessage(), responseBaBgtInfoData.getData().size());
        if (responseBaBgtInfoData.getResultCode().equals("000")) {
            for (GdszczBaBgtInfo s : responseBaBgtInfoData.getData()) {
                int existCount = baBgtInfoService.exists(s.getId());
                if (existCount == 0) {
                    if (first.isPresent()) {
                        s.setAgencyCode(first.get().getId());
                    }
                    baBgtInfoService.save(s);
                }
            }
        }
    }
}

